package com.weike.bsp.security.authentication.jwt

import org.slf4j.LoggerFactory
import org.springframework.http.server.reactive.ServerHttpRequest
import java.util.*

/**
 * 从[HttpServletRequest] 中获取token
 */
class JwtTokenExtractor {

    /**
     * 先充header中获取，如果不存在，再在url中获取
     */
    fun extract(request: ServerHttpRequest): String? {
        // first check the header...
        var token = extractHeaderToken(request)

        // bearer type allows a request parameter as well
        if (token == null) {
            logger.debug("Token not found in headers. Trying request parameters.")
            token = extractToken(request)
            if (token == null) {
                logger.debug("Token not found in request parameters.  Not an OAuth2 request.")
            }
        }
        return token
    }


    private fun extractToken(request: ServerHttpRequest): String? {
        return request.queryParams.getFirst(ACCESS_TOKEN)
//        return request.getParameter(ACCESS_TOKEN)
    }

    /**
     * Extract the OAuth bearer token from a header.
     *
     * @param request The request.
     * @return The token, or null if no OAuth authorization header was supplied.
     */
    private fun extractHeaderToken(request: ServerHttpRequest): String? {

        val headers = request.headers[TOKEN_HEADER] ?: emptyList()  //.getHeaders(TOKEN_HEADER)
        for (value in headers) {
            if (value.lowercase(Locale.getDefault()).startsWith(BEARER_TYPE.lowercase(Locale.getDefault()))) {
                var authHeaderValue = value.substring(BEARER_TYPE.length).trim { it <= ' ' }
                val commaIndex = authHeaderValue.indexOf(',')
                if (commaIndex > 0) {
                    authHeaderValue = authHeaderValue.substring(0, commaIndex)
                }
                return authHeaderValue
            }
        }
        return null
    }

    companion object {
        const val TOKEN_HEADER = "Authorization"
        const val ACCESS_TOKEN = "access_token"
        const val BEARER_TYPE = "Bearer"
        private val logger = LoggerFactory.getLogger(JwtTokenExtractor::class.java)
    }
}
